/* 数字 指令
* @Author: 彭小黑
* @Date: 2021-07-08 10:48:10
* @Last Modified by: 彭小黑
* @Last Modified time: 2021-09-20 14:46:11
 */
import type { App } from 'vue';

let inputNode: HTMLElement

const float = (arg: string = 'number', values: any | [string, number[]?], proxy: any, modifiers?: {}) => {
  const modelKeys = String(values[0]).split('.')
  // 最大最小
  const limits = values[1]
  
  inputNode.addEventListener('input', (e: Event) => {
    // 拷贝
    let copyProxy = proxy

    const keys = Object.keys(modifiers || {})
    let value = (e.target as any).value.replace(/[a-z]|[\u4e00-\u9fa5]|[^\x00-\xff]/ig, '') || ''

    // 为空说明只输入了 '/[a-z]|[\u4e00-\u9fa5]|[^\x00-\xff]/ig' 可以匹配的字符
    // 第一位不能为小数点
    if (!value || value === '.') {
      value = ''
      return
    }

    if (limits) {
      for (let i in limits) {
        if (isNaN(Number(limits[i]))) {
          console.error('value 的下标 ', i, '不能转换为数字')
          return
        }
      }
      value = value < limits[0] ? limits[0] : value > limits[1] ? limits[1] : value
    }

    if (arg == 'float') {
      value = String(value)
      // 只能有一位小数点
      // 小数长度 不能 大于 Number(keys[0]
      if (value.split('.').length > 2 || (value.indexOf('.') != -1 && value.substr(value.indexOf('.') + 1, value.length).length > (Number(keys[0] || 2)))) {
        // console.log('一位小数点出现2为', value, value.split('.').length);
        (e.target as any).value = value.substr(0, value.length - 1)
        return
      }

      // value = value.indexOf('.') == -1 ? Number(value).toFixed((keys && Number(keys[0])) || 2) : value
    } else {
      value = Number(value)
    }
    (e.target as any).value = value
    // 循环获取到最后一个key
    for (let i in modelKeys) {
      if (Number(i) == modelKeys.length - 1) {
        
        copyProxy[modelKeys[i]] = value
      } else {
        copyProxy = copyProxy[modelKeys[i]]
      }
    }
  })
}

/** 
* @author 彭小黑
* @param {array} value 接受一个数组 [第一个值为v-model 的 key（例如v-model='inputs.number' 那么key为 'inputs.number'）, 第二个值为数组[min, max]]
* @description 不支持 属性值中有小数 例如 inputs: { number.a: 1 }
*/
export default function num(app: App) {
  app.directive('num', (el, binding) => {
    console.log(binding);

    if (binding.arg && ['number', 'float'].indexOf(binding.arg) === -1) {
      console.error('传递给指令的参数只能为 number,float')
      return
    }
    
    if (!(binding.value instanceof Array) || binding.value.length < 1) {
      console.error("传递给指令的 value 值中必须包含一个 v-model 的 key，例如v-model='val'，则key 为 'val'")
      console.error('value：', binding.value)
      return
    }

    if (binding.value.length > 1 && binding.value[1] instanceof Array) {
      if (binding.value[1].filter((item: number | string) => isNaN(Number(item))).length) {
        console.error("传递给指令的 value 值中的第二个值必须为 整数或者小数")
        return
      }
    }
    // 获取input标签元素。el.children[0]兼容el-input
    inputNode = el.tagName === 'INPUT' ? el : el.children[0]

    // value 为一个数组 [min,max]。input的值不能大于max 并且不能小于 min。可以说是input值必须在min和max之间（或者为min和max）
    float(binding.arg, binding.value, binding.instance, binding.modifiers)
  })
}